/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cx1.service.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.cx1.model.Amenity;
import org.cx1.model.FurnishType;
import org.cx1.model.Listing;
import org.cx1.model.Photo;
import org.cx1.model.Place;
import org.cx1.model.PropertyType;
import org.cx1.model.StatusType;
import org.cx1.model.User;
import org.cx1.model.ZipCode;
import org.cx1.model.ds.MockDS;
import org.cx1.model.utils.KAmenityTypeIDs;
import org.cx1.model.utils.KFurnishTypeIDs;
import org.cx1.model.utils.KFurnishTypes;
import org.cx1.model.utils.KPlaceTypeIDs;
import org.cx1.model.utils.KPlaceTypes;
import org.cx1.model.utils.KPropertyTypeIDs;
import org.cx1.model.utils.KPropertyTypes;
import org.cx1.model.utils.KStatusTypeIDs;
import org.cx1.model.utils.KStatusTypes;
import org.cx1.model.utils.KZipCodes;
import org.cx1.model.utils.ServiceResponse;
import org.cx1.model.utils.SystemProperties;
import org.cx1.service.api.IAmenityService;
import org.cx1.service.api.IListingService;
import org.cx1.service.api.IPlaceService;
import org.cx1.service.impl.DAmenityService;
import org.cx1.service.impl.DListingService;
import org.cx1.service.impl.DPlaceService;
import org.cx1.service.impl.MAmenityService;
import org.cx1.service.impl.MListingService;
import org.cx1.service.impl.MPlaceService;

/**
 *
 * @author ECH
 */
public class ListingsCreator {

    //private IListingService service = new MListingService();
    //private IPlaceService placeService = new MPlaceService();
    //private IAmenityService amenityService = new MAmenityService();
    
    private IListingService service = new DListingService();
    private IPlaceService placeService = new DPlaceService();
    private IAmenityService amenityService = new DAmenityService();
    
    private List<User> users = MockDS.getUsers();
    private List<StatusType> statusTypes = KStatusTypes.getAll();
    private List<PropertyType> propertyTypes = KPropertyTypes.getAll();
    private String[] numbers = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"};
    private String[] floors = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21"};
    private List<ZipCode> zipCodes = KZipCodes.getAll();
    private List<FurnishType> furnishTypes = KFurnishTypes.getAll();
    private Double[] sqAreas = {20.1, 25.2, 30.3, 35.4, 40.5, 45.6, 50.7, 60.8, 65.9, 70.0};
    private Integer[] numBeds = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    private Integer[] numBaths = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    private String[] monthRates = {"15,000", "18,000", "23,000", "30,000", "35,000", "42,000", "50,000", "70,000", "100,000"};
        
    private String[] longMonthRates = {"17,000", "21,000", "27,000", "31,000", "36,000", "47,000", "50,000", "70,000", "100,000"};
    
    private String[] shortDayRates = {"900", "1,000", "1,200", "1,500", "2,000", "3,000", "5,000", "7,000", "10,000"};
    private String[] shortWeekRates = {"5,000", "7,000", "10,000", "11,000", "16,000", "17,000", "20,000", "27,000", "30,000"};
    private String[] shortMonthRates = {"15,000", "21,000", "27,000", "31,000", "36,000", "47,000", "50,000", "70,000", "100,000"};
    
    
    //private List<Photo> photos = MockDS.getStockPhotos();
    private List<Photo> photos = MockDS.getPhotos();

    private User randUser() {
        User user = null;
        user = users.get((int) (Math.random() * users.size()));
        return user;
    }

    private StatusType randStatusType() {
        return statusTypes.get((int) (Math.random() * statusTypes.size()));
    }

    private PropertyType randPropertyType() {
        return propertyTypes.get((int) (Math.random() * propertyTypes.size()));
    }

    private String randNumber() {
        return floors[(int) (Math.random() * floors.length)];
    }

    private String randFloor() {
        return numbers[(int) (Math.random() * numbers.length)];
    }

    private Set<Integer> pickedBuildings = new HashSet<Integer>();
    
    private Place randBuilding() {
        Place building = null;
        ServiceResponse<List<Place>> response = placeService.readAllByType(KPlaceTypeIDs.BUILDING, 0, 0);
        List<Place> buildings = response.getResponse();
                
        if (pickedBuildings.size() >= buildings.size()) {
            pickedBuildings = new HashSet<Integer>();
        }
        
        int indexPick = (int) (Math.random() * buildings.size());
        while (pickedBuildings.contains(indexPick)) {
            indexPick = (int) (Math.random() * buildings.size());
        }
        
        building = buildings.get(indexPick);
        pickedBuildings.add(indexPick);    
        
        System.out.println("CX: " + building.getTitle());
        
        return building;
    }
    
    private Place randVillage() {
        Place village = null;
        ServiceResponse<List<Place>> response = placeService.readAllByType(KPlaceTypeIDs.VILLAGE, 0, 0);
        List<Place> buildings = response.getResponse();
        village = buildings.get((int) (Math.random() * buildings.size()));
        return village;
    }

    private Place randCity() {
        Place city = null;
        ServiceResponse<List<Place>> response = placeService.readAllByType(KPlaceTypeIDs.CITY, 0, 0);
        List<Place> cities = response.getResponse();
        city = cities.get((int) (Math.random() * cities.size()));
        return city;
    }

    private ZipCode randZipCode() {
        return zipCodes.get((int) (Math.random() * zipCodes.size()));
    }

    private FurnishType randFurnishType() {
        return furnishTypes.get((int) (Math.random() * furnishTypes.size()));
    }

    private double randSqArea() {
        return sqAreas[(int) (Math.random() * sqAreas.length)];
    }

    private int randNumBeds() {
        return numBeds[(int) (Math.random() * numBeds.length)];
    }

    private int randNumBaths() {
        return numBaths[(int) (Math.random() * numBaths.length)];
    }

    private String randMonthRates() {
        return monthRates[(int) (Math.random() * monthRates.length)];
    }

    private String randLongMonthRates() {
        return longMonthRates[(int) (Math.random() * longMonthRates.length)];
    }
    
    private String randShortDayRates() {
        return shortDayRates[(int) (Math.random() * shortDayRates.length)];
    }
    
    private String randShortWeekRates() {
        return shortWeekRates[(int) (Math.random() * shortWeekRates.length)];
    }
    
    private String randShortMonthRates() {
        return shortMonthRates[(int) (Math.random() * shortMonthRates.length)];
    }
    
    private List<String> randAmenity() {
        List<String> amenities = new ArrayList<String>(0);
        Set<String> amenitySet = new HashSet(0);

        ServiceResponse<List<Amenity>> response = amenityService.readAll(0, 0);
        List<Amenity> records = response.getResponse();

        for (int i = 0; i < 10; i++) {
            if (records.size() > i) {
                Amenity record = records.get((int)(Math.random() * records.size()));
                if (record != null) {
                    amenitySet.add(record.getId());
                }
            }
        }
        amenities.addAll(amenitySet);
        return amenities;
    }

    //CX: make stock photos
    private Photo randPhoto() {
        Photo photo = null;
        photo = photos.get((int) (Math.random() * photos.size()));
        return photo;
    }

    // 1= long term, 2= short term, 3= both
    private int randLeaseTerm() {
        int leaseTerm = (int) (Math.random() * 3);
        if (leaseTerm == 0) {
            leaseTerm = 1;
        }
        return leaseTerm;
    }
    
    public void createListings() {
        Listing listing = null;

        for (int i = 0; i < 300; i++) {

            String titleType;
            String titleStruct;

            String propertyTypeID = randPropertyType().getId();
            
            //CX: basic info
            listing = new Listing();
            listing.setStatusTypeID(KStatusTypeIDs.FOR_RENT);
            listing.setPropertyTypeID(propertyTypeID);
            
            //CX: set lease term
            int leaseTerm = randLeaseTerm();
            if (leaseTerm == 1) {
                listing.setLeaseLongTerm(true);
                listing.setLeaseShortTerm(false);
            }
            else if (leaseTerm == 2) {
                listing.setLeaseLongTerm(false);
                listing.setLeaseShortTerm(true);                
            }
            else {
                listing.setLeaseLongTerm(true);
                listing.setLeaseShortTerm(true);                
            }
            
            
            Place place = null;
            Place district = null;
            String districtID = "";
            
            if (StringUtils.equalsIgnoreCase(propertyTypeID, KPropertyTypeIDs.CONDOMINIUM)) {
                place = randBuilding();
            }
            if (StringUtils.equalsIgnoreCase(propertyTypeID, KPropertyTypeIDs.HOUSE) || StringUtils.equalsIgnoreCase(propertyTypeID, KPropertyTypeIDs.TOWNHOUSE)) {
                place = randVillage();
            }
            
            if (place.getDistricts() != null && place.getDistricts().size() > 0) {
                district = place.getDistricts().get(0);
            }
            if (place.getDistrictIDs() != null && place.getDistrictIDs().size() > 0) {
                districtID = place.getDistrictIDs().get(0);
            }
            

            titleType = KPropertyTypes.getPropertyType(listing.getPropertyTypeID()).getTitle();
            if (StringUtils.equalsIgnoreCase(listing.getPropertyTypeID(), KPropertyTypes.CONDOMINIUM.getId())) {
                int rn = (int)(Math.random() * 2);
                if (rn == 1) {
                    titleType = "Condominium";
                }
                else {
                    titleType = "Apartment";                    
                }
                       
            }   

            //CX: location and address
            listing.setLat(place.getLat());
            listing.setLng(place.getLng());
            listing.setStructure(place.getTitle());
            
            listing.setNumber(randNumber());
            listing.setFloor(randFloor());

            titleStruct = listing.getStructure();

            //listing.setStreet("HV Dela Costa");
            listing.setCity(randCity().getTitle());
            listing.setZip(randZipCode().getId());
            listing.setRegion("National Capital");
            listing.setCountry("Philippines");

            //CX: property details
            listing.setFurnishTypeID(randFurnishType().getId());
            listing.setSqArea(randSqArea());
            
            int numBeds = randNumBeds();
            String strBeds = numBeds == 0 ? "Studio" : Integer.toString(numBeds) + " Bedroom";
            
            listing.setNumBedrooms(numBeds);
            listing.setNumBathrooms(randNumBaths());

            listing.getAmenityIDs().addAll(randAmenity());

            
            //CX: rate and availability
            listing.setLongMonthRate(randLongMonthRates());
            listing.setShortDayRate(randShortDayRates());
            listing.setShortWeekRate(randShortWeekRates());
            listing.setShortMonthRate(randShortMonthRates());
            
            //listing.setMonthRate(randMonthRates());
            //listing.setAvailabilityDate(new Date());

            //CX: additional info            
            listing.setTitle(strBeds + " " + titleType + " at " + titleStruct);
            listing.setDescription("Just a sample description: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");

            //CX: photos
            listing.getPhotoIDs().add(randPhoto().getId());

            //CX: back info
            listing.setCreatorID(randUser().getId());
            listing.setVerified(true);

            //CX: tags
            listing.getPlaceIDs().add(placeService.read(placeService.readIDByTitle("Makati").getResponse()).getResponse().getId());
            listing.getPlaceIDs().add(place.getId());
            
            if (!StringUtils.isEmpty(districtID)) {
                listing.getPlaceIDs().add(districtID);                
            }
            
            ServiceResponse<String> response = service.create(listing, true, true, true);
            if (!StringUtils.isEmpty(response.getResponse())) {
                service.postListing(response.getResponse());                
            }
            System.out.println("CX: " + response.getResponse());

        }
    }

    public void generateStockPhotos() {
        //CX: download 200 photos
        //CX: import to stockphotos
        //CX: numbered 1 - 200
        
        try {
            //File folder = new File("C:\\Users\\CX\\Desktop\\stock photos");
            //File folder = new File("C:\\Users\\ECH\\Desktop\\stock photos");
            File folder = new File(SystemProperties.STOCK_PHOTO_DIRECTORY);
            
            File[] listOfFiles = folder.listFiles();

            for (int i = 0; i < listOfFiles.length; i++) {
                if (listOfFiles[i].isFile()) {
                    System.out.println("File " + listOfFiles[i].getName());
                    
                    File srcFile = listOfFiles[i];                
                    File destFile = new File(SystemProperties.PHOTO_DIRECTORY + "/" + srcFile.getName());
                    //FileUtils.copyFileToDirectory(srcFile, destDir);
                    FileUtils.copyFile(srcFile, destFile, false);
                                
                    ImageProcessor proc = new ImageProcessor();
                    proc.createStandardSize(destFile);
                    proc.createPreviewSize(destFile);
                    
                    Photo photo = new Photo();
                    photo.setId(UUID.randomUUID().toString());
                    photo.setFilename(srcFile.getName());
                    
                    MockDS.getStockPhotos().add(photo);
                    MockDS.getPhotos().add(photo);
                            
                } 
            }            
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        /*
        for (int i = 1; i <= 200; i++) {
            Photo photo = new Photo();
            photo.setId("1");
            photo.setFilename("001-1.jpg");
            MockDS.getPhotos().add(new Photo());
        }
        */

        //CX: write photo
        //item.write(uploadedFile);

        //CX: write standard and preview sizes
        //ImageProcessor proc = new ImageProcessor();
        //proc.createStandardSize(uploadedFile);
        //proc.createPreviewSize(uploadedFile);

    }
    
    public static void main (String[] argv) {
        ListingsCreator creator = new ListingsCreator();
        
        for (int i = 0; i < 100; i++) {
            Place place = creator.randBuilding();
            System.out.println("CX: " + place.getTitle());
        }
        
        //creator.generateStockPhotos();
    }
}
